package com.zxmr.hospital.customer.action;

import java.util.List;

import com.alibaba.fastjson.JSON;
import com.zxmr.action.Request;
import com.zxmr.action.Response;
import com.zxmr.action.ResponsePayload;
import com.zxmr.action.ResultCode;
import com.zxmr.domain.Consult;
import com.zxmr.domain.Customer;
import com.zxmr.domain.Opportunity;
import com.zxmr.domain.account.AccountType;
import com.zxmr.domain.service.ConsultService;
import com.zxmr.domain.service.CustomerService;
import com.zxmr.domain.service.OpportunityService;
import com.zxmr.navigate.ExecuteException;
import com.zxmr.navigate.Executor;
import com.zxmr.util.ResourceManager;
import com.zxmr.util.UserTraceManager;
import com.zxmr.util.Utils;

public class ConsultAction extends Executor{

	enum method{
		add,
		query,
		listForOpp,
		listForCus,
		delete,
		update;
	}
	@Override
	public void execute(Request request, Response response) {
		
		try
		{
			method method = Enum.valueOf(method.class, this.getElement().getMethod());
			switch(method)
			{
			case add:
				add(request,response);
				break;
			case update:
				update(request,response);
				break;
			case query:
				query(request,response);
				break;
			case delete:
				delete(request,response);
				break;
			case listForOpp:
				listForAppo(request,response);
				break;		
			case listForCus:
				listForCus(request,response);
				break;	
			}

		}catch(Exception e)
		{
			ResponsePayload payload = new ResponsePayload();
			if(e instanceof ExecuteException)
			{
				payload.setValue(e.getMessage());
			}else
			{
				e.printStackTrace();
				payload.setValue("internal error");
			}
			response.setPayload(payload);
			response.setResult(ResultCode.COMPONENT_ERROR);
		}
	}

	private void add(Request request,Response response)throws ExecuteException
	{
		Consult consult = parseRequest(request);
		checkAddParameter(consult,request);
		
		consult.setAddUser(request.getAccount().getName());
		consult.setCompany(request.getAccount().getCompany());
		consult.setCreateTime(Utils.getCurrentTime());
		
		ConsultService service = new ConsultService();
		if(service.addConsult(consult))
		{
			String action = ResourceManager.getInstance().getMessage("com.zxmr.customer.addConsult", consult.getTitle());
			UserTraceManager.addTrace(action, request.getAccount());
		}
		else
			this.internalErrorResponse(response);
	}
	private void delete(Request request,Response response)throws ExecuteException
	{
		long id = 0;
		try
		{
			id = Long.parseLong(request.getRequestParameters().get("id"));
		}catch(Exception e)
		{
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.consult.errorPara"));
		}
		ConsultService service = new ConsultService();
		Consult consult = service.queryFullFieldConsult(id);
		if(consult == null || consult.getCompany() != request.getAccount().getCompany())
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.noauth.consultNotExist"));
		
		if(!request.getAccount().getName().equals(consult.getAddUser()) && request.getAccount().getAccountType() != AccountType.Supervisor)
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.noauth.deleteConsultOthers"));
		
		service.deleteConsult(consult);
	}
	private void checkAddParameter(Consult consult,Request request)throws ExecuteException
	{
		if(consult.getOpportunity() <= 0)
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.consult.noopportu"));
		if(Utils.isStringEmptyWithTrim(consult.getTitle()))
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.consult.notitle"));
		
		OpportunityService service = new OpportunityService();
		Opportunity opp = service.queryOpportunity(consult.getOpportunity());
		if(opp == null || opp.getCompany() != request.getAccount().getCompany())
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.noauth.oppNotExist"));
		
		// if the user is not the owner of the opportunity then it need has view to the opportunity
		if(request.getAccount().getAccountType() != AccountType.Supervisor 
				&& !request.getAccount().getName().equals(opp.getOwner())
				&& !this.isAuthorized(request.getAccount().getId(), "addConsultToOpportunityOthers"))
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.noauth.addConsultToOpportunityOthers"));
		
		
		consult.setCustomer(opp.getCustomer());
	}
	private void update(Request request,Response response)throws ExecuteException
	{
		
	}
	private Consult parseRequest(Request request)throws ExecuteException
	{
		try
		{
			return JSON.parseObject(request.getRequestParameters().get("parameters"), Consult.class);
		}catch(Exception e)
		{
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.consult.errorPara"));
		}
	}
	private void query(Request request,Response response)throws ExecuteException
	{
		
		long id = 0;
		try
		{
			id = Long.parseLong(request.getRequestParameters().get("id"));
		}catch(Exception e)
		{
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.consult.errorPara"));
		}
		ConsultService service = new ConsultService();
		Consult consult = service.queryFullFieldConsult(id);
		if(consult == null || consult.getCompany() != request.getAccount().getCompany())
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.noauth.consultNotExist"));
		
		OpportunityService oppService = new OpportunityService();
		Opportunity opp = oppService.queryOpportunity(consult.getOpportunity());
		
		// if it has queryOpportunityOthers then it can access to the consult
		if(request.getAccount().getAccountType()!=AccountType.Supervisor
				&& !request.getAccount().getName().equals(opp.getOwner()) && 
				!this.isAuthorized(request.getAccount().getId(), "queryConsultOthers"))
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.noauth.queryConsultOthers"));
		
		ResponsePayload payload = new ResponsePayload(JSON.toJSONString(consult));
		response.setPayload(payload);
	}
	
	private void listForAppo(Request request,Response response)throws ExecuteException
	{
		long apportunityId;
		try
		{
			apportunityId = Long.parseLong(request.getRequestParameters().get("opp"));
			
		}catch(Exception e)
		{
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.consult.errorPara"));
		}
		
		OpportunityService service = new OpportunityService();
		Opportunity opportunity = service.queryOpportunity(apportunityId);
		if(opportunity == null || opportunity.getCompany() != request.getAccount().getCompany())
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.noauth.oppNotExist"));
		
		if(request.getAccount().getAccountType()!=AccountType.Supervisor
				&& !request.getAccount().getName().equals(opportunity.getOwner()) && 
				!this.isAuthorized(request.getAccount().getId(), "queryConsultOthers"))
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.noauth.queryConsultOthers"));
		
		ConsultService conService = new ConsultService();
		List<Consult> result = conService.querySimpleFieldConsultByOpp(apportunityId);
		ResponsePayload payload = new ResponsePayload(JSON.toJSONString(result));
		response.setPayload(payload);
	}
	private void listForCus(Request request,Response response)throws ExecuteException
	{
		int customerId;
		try
		{
			customerId = Integer.parseInt(request.getRequestParameters().get("customer"));
			
		}catch(Exception e)
		{
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.consult.errorPara"));
		}
		
		CustomerService service = new CustomerService();
		Customer customer = service.queryCustomer(customerId);

		if(customer == null || customer.getCompany() != request.getAccount().getCompany())
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.noauth.nocustomer"));
		
		ConsultService conService = new ConsultService();
		List<Consult> result = conService.querySimpleFieldConsultByCustomer(customerId);
		ResponsePayload payload = new ResponsePayload(JSON.toJSONString(result));
		response.setPayload(payload);
	}
}
